﻿using System;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace HexTileBoard
{
    public class DynamicTextLine
    {
        /// <summary>
        /// Origins for sprite strings.
        /// x----x----x
        /// |         |
        /// x    x    x
        /// |         |
        /// x----x----x
        /// </summary>
        public enum OriginType//temp
        {
            BotLeft,
            BotMid,
            BotRight,
            MidLeft,
            Mid,
            MidRight,
            TopLeft,
            TopMid,
            TopRight
        }

        public string Text;                 // Text displayed
        public Vector2 OriginalPosition;    // ORIGINAL position of text
        public Vector2 Position;            // CURRENT position of text
        public SpriteFont Font;             // Font used to draw text
        public Color Color;                 // Color of text
        public Color ShadowColor;
        int ScrollStartTime;                // Time since inception of text to begin scrolling action in milliseconds/integer
        int ScrollEndTime;                  // Time since inception of text to end scrolling action in milliseconds/integer
        Vector2 ScrollDirection;            // Normalized scroll direction
        float ScrollSpeed;                  // Speed of scroll
        public float AlphaValue;            // Current alpha value (0-255)
        float AlphaFadeRate;                // Rate of fade
        int AlphaFadeStartTime;             // Time since inception of text to begin fade action in milliseconds/integer
        float AlphaFadeEndValue;            // Alpha value at which to end fade
        public Vector2 Origin;              // Origin to be drawn
        public float Scale = 1.0f;//temp
        //int ScaleStartTime;//temp
        //float ScaleRate;//temp
        public int LifeLength;              // Length of the text to exist in milliseconds/integer
        public int LifeExpired;             // Expired length of the text in milliseconds/integer

        public DynamicTextLine(string p_Text, Vector2 p_Position, SpriteFont p_Font, Color p_Color,
                       int p_LifeLength, OriginType p_OriginType)
        {
            this.Text = p_Text;
            this.OriginalPosition = p_Position;
            this.Position = p_Position;
            this.Font = p_Font;
            this.Color = p_Color;
            this.ScrollStartTime = 0;
            this.ScrollEndTime = 0;
            this.ScrollDirection = Vector2.Zero;
            this.ScrollSpeed = 0.0f;
            this.AlphaValue = 1.0f;
            this.AlphaFadeRate = 0.0f;
            this.AlphaFadeStartTime = 0;
            this.AlphaFadeEndValue = 1.0f;
            this.Origin = GetOrigin(p_OriginType);
            this.Scale = 1.0f;//temp, not in all functions
            //this.ScaleRate = .1f;//temp, not in all functions
            //this.ScaleStartTime = 0;//temp, not in all functions
            this.LifeLength = p_LifeLength;
            this.LifeExpired = 0;
        }

        public DynamicTextLine(string p_Text, Vector2 p_Position, SpriteFont p_Font, Color p_Color,
                       float p_AlphaValue, float p_AlphaFadeRate, int p_AlphaFadeStartTime, float p_AlphaFadeEndValue,
                       int p_LifeLength, OriginType p_OriginType)
        {
            this.Text = p_Text;
            this.OriginalPosition = p_Position;
            this.Position = p_Position;
            this.Font = p_Font;
            this.Color = new Color(p_Color.R, p_Color.G, p_Color.B);
            this.ScrollStartTime = 0;
            this.ScrollEndTime = 0;
            this.ScrollDirection = Vector2.Zero;
            this.ScrollSpeed = 0.0f;
            this.AlphaValue = MathHelper.Clamp(p_AlphaValue, 0.0f, 1.0f);
            this.AlphaFadeRate = p_AlphaFadeRate;
            this.AlphaFadeStartTime = p_AlphaFadeStartTime;
            this.AlphaFadeEndValue = MathHelper.Clamp(p_AlphaFadeEndValue, 0.0f, 1.0f);
            this.LifeLength = p_LifeLength;
            this.Origin = GetOrigin(p_OriginType);
            this.LifeExpired = 0;
        }

        public DynamicTextLine(string p_Text, Vector2 p_Position, SpriteFont p_Font, Color p_Color,
                       int p_StartTimeForScroll, int p_EndTimeForScroll, Vector2 p_ScrollDirection, float p_ScrollSpeed,
                       int p_LifeLength, OriginType p_OriginType)
        {
            p_ScrollDirection.Normalize();

            this.Text = p_Text;
            this.OriginalPosition = p_Position;
            this.Position = p_Position;
            this.Font = p_Font;
            this.Color = p_Color;
            this.ScrollStartTime = p_StartTimeForScroll;
            this.ScrollEndTime = p_EndTimeForScroll;
            this.ScrollDirection = p_ScrollDirection;
            this.ScrollSpeed = p_ScrollSpeed;
            this.AlphaValue = 1.0f;
            this.AlphaFadeRate = 0.0f;
            this.AlphaFadeStartTime = 0;
            this.AlphaFadeEndValue = 1.0f;
            this.LifeLength = p_LifeLength;
            this.Origin = GetOrigin(p_OriginType);
            this.LifeExpired = 0;
        }

        public DynamicTextLine(string p_Text, Vector2 p_Position, SpriteFont p_Font, Color p_Color,
                       int p_StartTimeForScroll, int p_EndTimeForScroll, Vector2 p_ScrollDirection, float p_ScrollSpeed,
                       float p_AlphaValue, float p_AlphaFadeRate, int p_AlphaFadeStartTime, float p_AlphaFadeEndValue,
                       int p_LifeLength, OriginType p_OriginType, Color _shadowColor)
        {
            p_ScrollDirection.Normalize();

            this.Text = p_Text;
            this.OriginalPosition = p_Position;
            this.Position = p_Position;
            this.Font = p_Font;
            this.Color = new Color(p_Color.R, p_Color.G, p_Color.B);
            this.ShadowColor = _shadowColor;
            this.ScrollStartTime = p_StartTimeForScroll;
            this.ScrollEndTime = p_EndTimeForScroll;
            this.ScrollDirection = p_ScrollDirection;
            this.ScrollSpeed = p_ScrollSpeed;
            this.AlphaValue = MathHelper.Clamp(p_AlphaValue, 0.0f, 1.0f);
            this.AlphaFadeRate = p_AlphaFadeRate;
            this.AlphaFadeStartTime = p_AlphaFadeStartTime;
            this.AlphaFadeEndValue = MathHelper.Clamp(p_AlphaFadeEndValue, 0.0f, 1.0f);
            this.LifeLength = p_LifeLength;
            this.Origin = GetOrigin(p_OriginType);
            this.LifeExpired = 0;
        }

        public void Update(GameTime gameTime)
        {
            LifeExpired += gameTime.ElapsedGameTime.Milliseconds;

            if (LifeExpired > ScrollStartTime && LifeExpired < ScrollEndTime)
                Position += (ScrollDirection * (ScrollSpeed * gameTime.ElapsedGameTime.Milliseconds));

            if (AlphaValue != AlphaFadeEndValue && LifeExpired >= AlphaFadeStartTime)
            {
                AlphaValue += AlphaFadeRate * gameTime.ElapsedGameTime.Milliseconds;
                AlphaValue = MathHelper.Clamp(AlphaValue, 0.0f, 1.0f);
                Color.A *= (byte)AlphaValue;
            }

            //if (LifeExpired >= ScaleStartTime)

        }

        /// <summary>
        /// Updates the position the text originally occupied before starting to move.
        /// Changes the original position by specifying an value completely different from the original position.
        /// Useful to change relative text position on a screen when scrolling.
        /// Example:
        /// Position: 10,10
        /// OriginalPosition: 4,4
        /// p_UpdateOriginalPosition: 1,1
        /// After function:
        /// Position = 7,7
        /// OriginalPosition = 1,1
        /// </summary>
        /// <param name="p_UpdatedOriginalPosition">The position that is being designated as the starting location of the text.</param>
        public void UpdateOriginalPosition(Vector2 p_UpdatedOriginalPosition)
        {
            Position = Position - OriginalPosition + p_UpdatedOriginalPosition;
            OriginalPosition = p_UpdatedOriginalPosition;
        }

        /// <summary>
        /// Updates the position the text originally occupied before starting to move.
        /// Changes the original value incrementally.
        /// Example:
        /// Position: 10,10
        /// OriginalPosition: 4,4
        /// p_IncrementalChangeToOriginalPosition: 1,1
        /// After function:
        /// Position = 11,11
        /// OriginalPosition = 5,5
        /// </summary>
        /// <param name="p_IncrementalChangeToOriginalPosition">The position that is being designated as the starting location of the text.</param>
        public void UpdateOriginalPositionIncremental(Vector2 p_IncrementalChangeToOriginalPosition)
        {
            Position += p_IncrementalChangeToOriginalPosition;
            OriginalPosition += p_IncrementalChangeToOriginalPosition;
        }

        /// <summary>
        /// Calculates the origin.
        /// </summary>
        /// <param name="p_OriginType">Vector2 values of origin.</param>
        /// <returns>Vector2 of the origin based on type.</returns>
        private Vector2 GetOrigin(OriginType p_OriginType)
        {
            Vector2 o = this.Font.MeasureString(this.Text);

            switch (p_OriginType)
            {
                case OriginType.BotLeft:
                    o.X = 0;
                    break;
                case OriginType.BotMid:
                    o.X /= 2;
                    break;
                case OriginType.BotRight:
                    break;
                case OriginType.Mid:
                    o.X /= 2;
                    o.Y /= 2;
                    break;
                case OriginType.MidLeft:
                    o.X = 0;
                    o.Y /= 2;
                    break;
                case OriginType.MidRight:
                    o.Y /= 2;
                    break;
                case OriginType.TopLeft:
                    o = Vector2.Zero;
                    break;
                case OriginType.TopMid:
                    o.Y = 0;
                    o.X /= 2;
                    break;
                case OriginType.TopRight:
                    o.Y = 0;
                    break;
            }

            return o;
        }
    }
}
